<?php
namespace App\Controllers\Admin\System;

use App\Models\System\SystemConfig;
use App\Models\System\SystemUser;
use App\Models\UploadLog;
use Exception;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class UploadController
{
    public $allowType = ['image/jpeg'];

    public $uploadDirectory = 'uploads/';

    /**
     * 上传文件
     * @auth
     */
    public function index(Request $request, Response $response)
    {
        if ($request->getMethod() == 'POST') {
            $files = $request->getUploadedFiles();
            $fileKeys = array_keys($files);
            if (!isset($fileKeys[0]) || isset($fileKeys[1])) {
                throw new Exception('上传参数错误');
            }
            $files = $files[$fileKeys[0]];
            if (($files instanceof \Psr\Http\Message\UploadedFileInterface) !== true) {
                throw new Exception('上传文件接收错误');
            }
            unset($fileKeys);
            if ($files->getError() !== 0) {
                throw new Exception('上传文件错误');
            }
            $mimeType = $files->getClientMediaType();
            if (!in_array($mimeType, $this->allowType)) {
                throw new Exception('不允许上传该类型文件');
            }

            $size = $files->getSize();
            $size = ceil($size / 1024);

            $createdBy = SystemUser::getIdByToken();
            if ($createdBy <= 0) {
                throw new Exception('上传者ID获取错误');
            }

            // 上传目录
            $configRs = SystemConfig::getConfig('system');
            !isset($configRs['upload_rule']) && $configRs['upload_rule'] = 'Y/m-d';
            $configRs = $configRs['upload_rule'];
            $filePathName = ROOT_PATH . 'public/' . $this->uploadDirectory;
            $filePathName .= date($configRs) . DIRECTORY_SEPARATOR;
            unset($configRs);
            if (is_dir($filePathName) === false) {
                $isMake = mkdir($filePathName, 0777, true);
                if ($isMake === false) {
                    throw new Exception('上传目录创建错误');
                }
                unset($isMake);
            }

            // 上传文件内容SHA1
            $filePathName .= sha1_file($files->getStream()->getMetadata('uri'));
            $fileName = $files->getClientFilename();
            $filePathName .= substr($fileName, strrpos($fileName, '.'));

            $files->moveTo($filePathName);

            if ($files->isMoved() !== true) {
                throw new Exception('上传文件保存错误');
            }
            unset($files);

            $filePathName = str_replace(ROOT_PATH . 'public', '', $filePathName);

            $log = new UploadLog;
            $log->type = 1;
            $log->url = $filePathName;
            $log->name = mb_strlen($fileName) > 30 ? mb_substr($fileName, 0, 27) . '...' : $fileName;
            $log->mime = strlen($mimeType) > 30 ? substr($mimeType, 0, 27) . '...' : $mimeType;
            $log->size = $size;
            $log->created_by = $createdBy;
            $log->save();
            if (!isset($log->id) || $log->id <= 0) {
                throw new Exception('上传记录保存错误');
            }

            $response->getBody()->write($filePathName);
            return $response;
        } elseif ($request->getMethod() == 'DELETE') {
            $streamBody = $request->getBody();
            $fileName = $streamBody->read($streamBody->getSize());
            if ($fileName == '') {
                throw new Exception('入参参数错误');
            }

            $createdBy = SystemUser::getIdByToken();
            if ($createdBy <= 0) {
                throw new Exception('上传者ID获取错误');
            }

            $infoRs = UploadLog::select('id')
                ->where('type', 1)
                ->where('url', $fileName)
                ->where('created_by', $createdBy)
                ->orderBy('id', 'desc')
                ->first();
            if (!isset($infoRs->id)) {
                throw new Exception('上传记录未找到');
            }
            UploadLog::where('id', $infoRs->id)->delete();

            $fileName = ROOT_PATH . 'public' . $fileName;
            if (file_exists($fileName) !== true) {
                throw new Exception('文件不存在');
            }

            unlink($fileName);
            return $response;
        }
    }
}
